1 /** 2 Copyright: Copyright (c) 2021, Joakim Brännström. All rights reserved. 3 License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost Software License 1.0) 4 Author: Joakim Brännström (joakim.brannstrom@gmx.com) 5 */ 6 module code_checker.cache; 7 8 import logger = std.experimental.logger; 9 import std.exception : collectException; 10 11 import my.path; 12 13 import code_checker.database : TrackFile; 14 15 struct FileStatCache { 16 import std.datetime : Clock, SysTime; 17 import std.file : timeLastModified; 18 import my.hash : checksum, makeChecksum64, Checksum64; 19 20 TrackFile[AbsolutePath] cache_; 21 SysTime[AbsolutePath] timeStamp_; 22 Checksum64[AbsolutePath] checkSum_; 23 24 TrackFile get(AbsolutePath p) @safe nothrow { 25 try { 26 return cache_.require(p, TrackFile(p, getChecksum(p), getTimeStamp(p))); 27 } catch (Exception e) { 28 } 29 return TrackFile.init; 30 } 31 32 SysTime getTimeStamp(AbsolutePath p) @safe nothrow { 33 try { 34 return timeStamp_.require(p, timeLastModified(p)); 35 } catch (Exception e) { 36 logger.trace(e.msg).collectException; 37 } 38 return Clock.currTime; 39 } 40 41 Checksum64 getChecksum(AbsolutePath p) @trusted nothrow { 42 try { 43 return checkSum_.require(p, checksum!makeChecksum64(p)); 44 } catch (Exception e) { 45 logger.trace(e.msg).collectException; 46 } 47 return Checksum64.init; 48 } 49 50 void drop(AbsolutePath p) @safe nothrow { 51 cache_.remove(p); 52 timeStamp_.remove(p); 53 checkSum_.remove(p); 54 } 55 } 56 57 TrackFile getTrackFile(Path p) @trusted nothrow { 58 import std.datetime : Clock; 59 import std.file : timeLastModified; 60 import my.hash : checksum, makeChecksum64, Checksum64; 61 62 auto cs = () { 63 try { 64 return checksum!makeChecksum64(AbsolutePath(p)); 65 } catch (Exception e) { 66 logger.trace(e.msg).collectException; 67 } 68 return Checksum64.init; 69 }(); 70 71 auto ts = () { 72 try { 73 return timeLastModified(p); 74 } catch (Exception e) { 75 logger.trace(e.msg).collectException; 76 } 77 return Clock.currTime; 78 }(); 79 80 return TrackFile(p, cs, ts); 81 } 82 83 bool isSame(const TrackFile tf, const AbsolutePath p, ref FileStatCache fcache) { 84 import std.math : abs; 85 86 if ((tf.timeStamp - fcache.getTimeStamp(p)).total!"msecs".abs < 20) { 87 debug logger.trace("timestamp unchanged ", p); 88 return true; 89 } 90 91 if (tf.checksum == fcache.getChecksum(p)) { 92 debug logger.trace("checksum unchanged ", p); 93 return true; 94 } 95 96 return false; 97 }